#import <QuartzCore/QuartzCore.h>
#import "ALTimelineScaleLabel.h"
#import "NSObject+BlockObservation.h"
#import "NSShadow+MCAdditions.h"


#pragma mark Constants
static const CGFloat ALScaleDateFieldBottomPadding = 10.0f;
static const CGFloat ALScaleDateFieldHeight = 20.0f;
static const CGFloat ALScaleTickLength = 10.0f;
static const CGFloat ALScaleTickWidth = 2.0f;

#pragma mark Keys
static NSString* const ALScaleLabelDateKey = @"date";


#pragma mark -
#pragma mark Class Globals
static NSDictionary *ALScaleDateFieldAttributes;
static NSDateFormatter *ALScaleDateFormatter;
static NSColor *ALScaleTickColor;
static NSShadow *ALScaleTickShadow;


#pragma mark -
@interface ALTimelineScaleLabel ()
@property (nonatomic, retain) NSTextField *dateField;
@end


#pragma mark -
@interface ALTimelineScaleLabel (ALTimelineScaleTickPrivateMethods)
-(NSTextField *)dateFieldGenerator;
-(NSAttributedString *)attributedDateString_;
-(NSRect)dateFieldRectForBounds:(NSRect)bounds;
@end


#pragma mark -
@implementation ALTimelineScaleLabel

@synthesize date;
@synthesize oldPosition;
@synthesize currentPosition;
@synthesize dateField;


#pragma mark -
#pragma mark Initialization

+(void)initialize {
	if (self != [ALTimelineScaleLabel class])
		return;
	ALScaleDateFieldAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[NSFont labelFontOfSize:[NSFont labelFontSize]], NSFontAttributeName, [NSColor lightGrayColor], NSForegroundColorAttributeName, nil];
	ALScaleDateFormatter = [[NSDateFormatter alloc] init];
	ALScaleTickColor = [NSColor colorWithCalibratedWhite:0.5f alpha:1.0f];
	NSColor *shadowColor = [NSColor colorWithCalibratedWhite:0.0f alpha:0.4f];
	ALScaleTickShadow = [[NSShadow alloc] mcInitWithColor:shadowColor offset:NSMakeSize(0, -2) blurRadius:3];
}

-(id)initWithFrame:(NSRect)frameRect {
	if (!(self = [super initWithFrame:frameRect]))
		return nil;
	[self setDateField:[self dateFieldGenerator]];
	[self addSubview:[self dateField]];
	AMBlockTask dateTask = ^(id object, NSDictionary *change) {
		[[self dateField] setAttributedStringValue:[self attributedDateString_]];
	};
	[self addObserverForKeyPath:ALScaleLabelDateKey task:dateTask];
	return self;
}


#pragma mark -
#pragma mark Size and layout

-(void)resizeSubviewsWithOldSize:(NSSize)oldSize {
	NSRect dateFieldRect = [self dateFieldRectForBounds:[self bounds]];
	[[self dateField] setFrame:dateFieldRect];
}

-(void)sizeToFitWidth {
	NSTextField *field = [self dateFieldGenerator];
	[field setAttributedStringValue:[self attributedDateString_]];
	CGFloat fieldWidth = ceil([[field cell] cellSize].width);
	NSRect frame = [self frame];
	frame.size.width = fieldWidth;
	[self setFrame:frame];
}

-(CGFloat)tickPositionInRect:(NSRect)aRect {
	return aRect.origin.x + (aRect.size.width / 2);
}

-(NSRect)dateFieldRectForBounds:(NSRect)bounds {
	NSRect dateFieldRect = bounds;
	dateFieldRect.origin.y = ALScaleDateFieldBottomPadding;
	dateFieldRect.size.height = ALScaleDateFieldHeight;
	return dateFieldRect;
}

-(NSTextField *)dateFieldGenerator {
	NSRect dateFieldRect = [self dateFieldRectForBounds:[self bounds]];
	NSTextField *field = [[NSTextField alloc] initWithFrame:dateFieldRect];
	[field setBordered:NO];
	[field setEditable:NO];
	[field setDrawsBackground:NO];
	return field;
}


#pragma mark -
#pragma mark Date formatting

+(void)setDateFormatWithInterval:(NSDateComponents *)interval {
	if ([interval year] != NSUndefinedDateComponent)
		[ALScaleDateFormatter setDateFormat:@"yyyy"];
	else if ([interval month] != NSUndefinedDateComponent)
		[ALScaleDateFormatter setDateFormat:@"MMMM yyyy"];
	else
		[ALScaleDateFormatter setDateStyle:NSDateFormatterLongStyle];
}

-(NSAttributedString *)attributedDateString_ {
	if (![self date])
		return nil;
	NSString *dateString = [ALScaleDateFormatter stringFromDate:[self date]];
	return [[NSAttributedString alloc] initWithString:dateString attributes:ALScaleDateFieldAttributes];
}


#pragma mark -
#pragma mark Drawing

-(void)drawRect:(NSRect)dirtyRect {
	NSRect bounds = [self bounds];
	CGFloat tickPosition = [self tickPositionInRect:bounds];
	NSPoint topPoint = NSMakePoint(tickPosition, NSMaxY(bounds));
	NSPoint bottomPoint = NSMakePoint(tickPosition, NSMaxY(bounds) - ALScaleTickLength);
	[ALScaleTickColor setStroke];
	[ALScaleTickShadow set];
	[NSBezierPath setDefaultLineWidth:ALScaleTickWidth];
	[NSBezierPath strokeLineFromPoint:topPoint toPoint:bottomPoint];
	[NSBezierPath setDefaultLineWidth:0];
}

@end
